package com.ququ.syb.business.transfer.service;

import com.ququ.common.result.Result;
import com.ququ.syb.business.transfer.fegin.AccountFegin;
import com.ququ.syb.business.transfer.fegin.BalanceFegin;
import com.ququ.syb.business.transfer.fegin.PayChannelFegin;
import com.ququ.syb.business.transfer.fegin.TransferOrderFegin;
import com.ququ.syb.common.constant.FlowTypeConstant;
import com.ququ.syb.common.constant.ResultStatusConstant;
import com.ququ.syb.common.constant.TransferStatusConstant;
import com.ququ.syb.common.constant.TransferTypeConstant;
import com.ququ.syb.common.pojo.AccountChannelBalance;
import com.ququ.syb.common.pojo.AccountInfo;
import com.ququ.syb.common.pojo.PayChannel;
import com.ququ.syb.common.pojo.TransferOrder;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

@Service
public class TransferBusinessSevice {

    private Logger logger = LoggerFactory.getLogger(TransferBusinessSevice.class);

    @Autowired
    private PayChannelFegin payChannelFegin;
    @Autowired
    private TransferOrderFegin transferOrderFegin;
    @Autowired
    private BalanceFegin balanceFegin;
    @Autowired
    private AccountFegin accountFegin;

    /**
     * 创建转账订单
     */
    private Result<TransferOrder> createTransferOrder(String outorderno,String fromaccount,String frompaychannelid,String toaccount,String topaychannelid,Long amount,Integer type,String appcode){
        type=type==null?TransferTypeConstant.ACCOUNT_TRANSFER:type;
        if (type == TransferTypeConstant.ACCOUNT_TRANSFER){
            if (fromaccount.equals(toaccount))
                return new Result<>(-1,"不允许相同账户间同通道号转账");
            if (!frompaychannelid.equals(topaychannelid))
                return new Result<>(-1,"不允许不同账户跨通道转账");
        }else {
            if (frompaychannelid.equals(topaychannelid))
                return new Result<>(-1, "通道间转账不允许相同通道号");
            if (!fromaccount.equals(toaccount))
                return new Result<>(-1,"不允许不同账户跨通道转账");
        }
        TransferOrder transferOrder = new TransferOrder();
        transferOrder.setOutorderno(outorderno);
        transferOrder.setFromaccount(fromaccount);
        transferOrder.setFrompaychannelid(frompaychannelid);
        transferOrder.setToaccount(toaccount);
        transferOrder.setTopaychannelid(topaychannelid);
        transferOrder.setType(type);
        transferOrder.setAmount(amount);
        transferOrder.setAppcode(appcode);
        return transferOrderFegin.saveTransferOrder(transferOrder);
    }

    /**
     * 转账逻辑
     */
    public Result<TransferOrder> transferBusiness(String outorderno,String fromaccount,String frompaychannelid,String toaccount,String topaychannelid,Long amount,Integer type,String appcode){
        Result<TransferOrder> transferOrderResult = createTransferOrder(outorderno, fromaccount, frompaychannelid, toaccount, topaychannelid, amount, type, appcode);
        if (transferOrderResult.getStatus() != ResultStatusConstant.SUCCESS)
            return transferOrderResult;
        TransferOrder transferOrder = transferOrderResult.getData();
        if (!checkAccount(fromaccount)) {
            transferFail(transferOrder,"转出方账户冻结");
            return new Result<>(-1, "转出方账户冻结");
        }
        if (!checkAccount(toaccount)) {
            transferFail(transferOrder,"转入方账户冻结");
            return new Result<>(-1, "转入方账户冻结");
        }
        if (type == TransferTypeConstant.CHANNEL_TRANSFER && !channelCanTransfer(frompaychannelid, topaychannelid)){
            transferFail(transferOrder,"不是同一家通道，不允许跨通道转账");
            return new Result<>(-1,"不是同一家通道，不允许跨通道转账");
        }
        if (!checkAccountBalance(fromaccount, frompaychannelid, amount)){
            transferFail(transferOrder,"转出方通道余额不足");
            return new Result<>(-1,"转出方通道余额不足");
        }
        transferDeduct(transferOrder.getTradenum(),amount,fromaccount,frompaychannelid,appcode);
        transferReceipt(transferOrder.getTradenum(),amount,toaccount,topaychannelid,appcode);
        transferOrder = transferSuccess(transferOrder);
        return new Result<>(transferOrder);
    }


    /**
     * 检查账户是否冻结
     */
    private boolean checkAccount(String accountid){
        AccountInfo accountInfo = accountFegin.getAccountInfo(accountid).getData();
        if (accountInfo == null || accountInfo.getStatus() != 1)
            return false;
        else
            return true;
    }


    /**
     * 检查通道间是否允许转账
     */
    private boolean channelCanTransfer(String frompaychannelid,String topaychannelid){
        PayChannel fromChannel = payChannelFegin.getPayChannel(frompaychannelid).getData();
        PayChannel toChannel = payChannelFegin.getPayChannel(topaychannelid).getData();
        if (fromChannel.getSharebalance() != null && toChannel.getSharebalance() != null && fromChannel.getSharebalance().equals(toChannel.getSharebalance()))
            return true;
        else
            return false;
    }


    /**
     * 检查转账余额是否足够
     */
    private boolean checkAccountBalance(String fromaccount,String frompaychannelid, Long amount){
        AccountChannelBalance accountChannelBalance = balanceFegin.getAccountChannelBalance(fromaccount,frompaychannelid).getData();
        if (amount <= accountChannelBalance.getBalance())
            return true;
        else
            return false;
    }

    /**
     * 转出方资金变动
     */
    private void transferDeduct(String tradenum,Long amount,String fromaccount,String frompaychannelid,String appcode){
        balanceFegin.addBalance(fromaccount,frompaychannelid,0-amount,3,tradenum,FlowTypeConstant.TRANSFER_OUT,appcode,tradenum+"转账订单转出");
    }



    /**
     * 转入方资金变动
     */
    private void transferReceipt(String tradenum,Long amount,String toaccount,String topaychannelid,String appcode){
        balanceFegin.addBalance(toaccount,topaychannelid,amount,3,tradenum,FlowTypeConstant.TRANSFER_IN,appcode,tradenum+"转账订单转入");
    }


    /**
     * 转账成功处理
     */
    private TransferOrder transferSuccess(TransferOrder transferOrder){
        transferOrder.setStatus(TransferStatusConstant.SUCCESS);
        transferOrderFegin.updateTransferOrder(transferOrder);
        return transferOrder;
    }


    /**
     * 转账失败处理
     */
    private TransferOrder transferFail(TransferOrder transferOrder,String failreason){
        transferOrder.setStatus(TransferStatusConstant.FAIL);
        transferOrder.setFailreason(failreason);
        transferOrderFegin.updateTransferOrder(transferOrder);
        return transferOrder;
    }
}
